#twine twine is a game engine. you can make text-based choose-your-own-adventure type games with twine. in a twine game, you explore and make choices by clicking (link:"links")[links, like the one you just clicked]. you can also use variables to track the player's choices and affect later outcomes. because a twine game is an .html file, you can do anything you want with html and css, like changing the font, text color, background color, etc. here's an example of a short twine game: (b4r:"double")+(b4r-colour:#634f08)+(b4r-size:6)[{ }You are in a dark dungeon. Faint light glimmers ahead. (link:"Step forward.")[You take several tentative steps towards the light, blinking as your eyes adjust. |choices>[On a plinth before you are a (link: "crystal orb")[{ (replace: ?choices)[On a plinth before you are a crystal orb and a rusted dagger.] (show: ?orb) }] and a (link: "rusted dagger")[{ (replace: ?choices)[On a plinth before you are a crystal orb and a rusted dagger.] (show: ?dagger)}].]{ }|orb)[ You grab the orb and are immediately overwhelmed with visions of the near-infinite permutations of reality: past, present, and future. You fall on your butt.]{ }|dagger)[ You grab the dagger and hear the cackle of a disembodied spirit, followed by a cold chill. You have been possessed by a malevolent ghost.] ]]<fakegame| for a big reference sheet of all the fun weird stuff you can do in twine, [[click here->reference]]. πŸ§ƒπŸ₯•πŸ₯«#twine reference sheet ##visuals [[change background color]] [[misc styling]] ##hypertext [[passage links]] [[inline links]] [[mouseovers]] ##programming [[boolean variables]] [[string variables]] [[number variables]] [[countdown timer]] [[probability]] [[write out phrases]] [[write out letters]] [[write out paragraphs]]The sun was approaching the [[horizon->sunset]].You see a countdown timer on a screen, and two buttons underneath. =><= (live: .25s)[<h3>(print: (round: 10 - (time / 1000)))</h3>]<countdown| <span class="red">[[red button]]</span> &emsp; <span class="green">[[green button]]</span> (after: 10s)[(go-to:"dead")]{(set: $holywater to false) (set: $thermometer to false) (set: $flashlight to false) }Before you head out to go exorcise this demon, you look at your table of available tools. (link:"Holy water. ")[(set: $holywater to true)(append:?toolzone)[You got the holy water. ]](link:"Thermometer. ")[(set: $thermometer to true)(append:?toolzone)[You got the thermometer. ]](link:"Flashlight. ")[(set: $flashlight to true)(append:?toolzone)[You got the flashlight. ]] []<toolzone| [[OK, let's go!]]{(set: $names to (a:"Lucy","Omar","Bill","Tomoko","Ines","Marco","Jack","Wei","Anna","Miguel")) }You arrive at the entrance of a fancy castle. The footman asks for your name. [(link-rerun:"What was your name again...")[(set: $names to (rotated: 1, ...$names)) (print:1st of $names)? (link:"Yes, that's it.")[(replace:?nameq)[What was your name again... (print:1st of $names)? Yes, that's it. The footman announces your name for all in the hall to hear. "(print:1st of $names) has arrived!"])]]]<nameq| (display:"backtoreference"){(set: $numberofbars to 0) }You break into the chocolate bar factory at midnight. You can steal as many chocolate bars as you want!!! (link-repeat: "Grab a bar!")[(if: $numberofbars is 0)[ You grabbed a bar.(set: $numberofbars to it + 1)](else:)[ You grabbed another bar.(set: $numberofbars to it + 1)]] [[OK, time to leave.->leave]]{(set: $probability to 15) }You're thinking about eating the last slice of cake in the fridge. (link:"No, don't eat it.")[(set: $probability to it + 15)(replace:?probs)[(print: $probability)%]You went to mow the lawn, but you're still thinking about eating the last slice of cake in the fridge. (link:"No, don't eat it.")[(set: $probability to it + 15)(replace:?probs)[(print: $probability)%]You went on a bike ride, but you're still thinking about eating the last slice of cake in the fridge. (link:"No, don't eat it.")[(set: $probability to it + 15)(replace:?probs)[(print: $probability)%]You watched some TV, but you're still thinking about eating the last slice of cake in the fridge. (link:"No, don't eat it.")[(set: $probability to it + 15)(replace:?probs)[(print: $probability)%]You washed the dishes, but you're still thinking about eating the last slice of cake in the fridge. (link:"No, don't eat it.")[(set: $probability to it + 15)(replace:?probs)[(print: $probability)%]You're lying in bed, but you're still thinking about eating the last slice of cake in the fridge. (link:"No, don't eat it.")[YOU REALLY WANT TO EAT IT!]]]]]] [[Eat it!]] (The probability that your roommate ate the cake is [(print: $probability)%]<probs|.) β€” text alignment: <== one, =><===== two, =><= three, =====><= four, ==> five <== β€” text formatting: normal&emsp;(text-style: "bold")[bold]&emsp;(text-style: "italic")[italic]&emsp;(text-style: "strike")[strikethrough] normal&emsp;(text-style: "subscript")[subscript]&emsp;(text-style: "superscript")[superscript] (text-style: "mark")[highlit text] (text-style: "blur")[blurry text]&emsp;(text-style: "blurrier")[blurrier text] (text-style: "mirror")[backwards text] β€” animations: (text-style: "blink")[blinking text]&emsp;(text-style: "fade-in-out")[fading text] (text-style: "rumble")[vertical vibration]&emsp;(text-style: "shudder")[horizontal vibration]&emsp;(text-style: "buoy")[vertical drifting]&emsp;(text-style: "sway")[horizontal drifting] (text-rotate-z:-45)[rotated](text-rotate-z:-25)[ text] (display:"backtoreference")The sky began to grow [[warm->night]].Slowly, the sun set. (after: 4s)[(t8n:"dissolve")[Time to [[go to the club?]]]]wooooooooo [[back to reference->reference]](display:"dead")Crisis averted! <span style="background-color:#000000;padding-right:10px;padding-left:10px;">[[back to reference->reference]]</span>The facility explodes and you die. <span style="background-color:#000000;padding-right:10px;padding-left:10px;">[[back to reference->reference]]</span>pages in twine are called passages, imagine them like passages in a dungeon. will you go [[left]] or [[right]]?you are in a mysterious grotto, where you can [[climb on some rocks]] or [[peek behind the waterfall]].you are in a quiet grove. from up ahead you hear a [[majestic whinnying]], maybe investigate? on second thought, you could also [[go check out that cave]]...you slipped and fell on your butt. (display:"backtoreference")there's a nymph she's chill as hell (display:"backtoreference")<span style="background-color:#54644e;padding-right:10px;padding-left:10px;">[[back to reference->reference]]</span>you find and befriend a magical horse. (display:"backtoreference")big mistake, you are frodo'd by a giant spider. (display:"backtoreference")β€” most of the behavior of inline links can be modified to work with mouseovers instead, which gives you another way to explore the text. the following paragraph contains a bunch of different mouseover behaviors. [You enter the (link:"shop",(action:'mouseover'))[dark, dusty shop] and approach the empty counter. A bell sits there, but hitting it doesn't make a sound. After (link-repeat:"waiting",(action:'mouseover'))[(append:?long)[, long]] a [long]<long| time, you notice a (link:"mysterious",(action:'mouseover'))[terrifying] shape shifting in a cobwebbed corner. (link-reveal:"You scream",(action:'mouseover'))[, but there's no one here to help you. (link:"You run for the door",(action:'mouseover'))[(replace:?toolate)[ ^^it's too late^^]]].]<toolate| (display:"backtoreference")β€” in twine you can have inline links that don't take you to a new passage. these can let you do fun and playful things with the text. they have various functionalities. randomness can be incorporated. (link:"Throw a rock at that lightbulb!")[You threw a rock at the lightbulb and now you're in the dark.] (link-reveal:"I wonder what I'll eat for lunch today...")[ maybe a baked potato?] (link-repeat:"You feel sleepy.")[ So sleepy.] (link-repeat:"Look out the window.")[ A (either:"blue","silver","yellow","red","green","black") car (either:"drives","zooms","speeds","putters","slides") by.] (link-rerun: "Look at the clouds...")[ (either:"that","this") one (either:"looks like","resembles") a (either:"dog","boat","pillow","fish","peach","windmill","bear","lamp","tomato","tree").] β€” you can also incorporate randomness in non-link contexts. This sentence, which mentions the city (either:"Toronto","Busan","Chiba","Jakarta","Santiago"), picks randomly from a list of 5 cities every time the pages is loaded. β€” the following sentence cycles randomly through a list of 5 sentences. (live: 2s)[(either:"It looks like it might rain soon.","I smell barbecue next door.","A cool bird just flew by.","I heard a dog barking.","I forgot to switch the laundry.")] β€” inline links can involve a number of dynamic transitions. (link-rerun:"fade")[(t8n: "fade")[&emsp;fade]] (link-rerun:"slow fade")[(t8n: "fade")+(transition-time: 3s)[&emsp;slow fade]] (link-rerun:"rumble")[(t8n: "rumble")[&emsp;rumble]] (link-rerun:"shudder")[(t8n: "shudder")[&emsp;shudder]] (link-rerun:"pulse")[(t8n: "pulse")[&emsp;pulse]] (link-rerun:"zoom")[(t8n: "zoom")[&emsp;zoom]] (link-rerun:"slide")[(t8n: "slide-left")[&emsp;slide]] (link-rerun:"fade slide")[(t8n: "fade-left")[&emsp;fade slide]] all transitions can have their timing adjusted. (display:"backtoreference")You hightail it outta there. You grabbed { (if: $numberofbars < 10)[fewer than ten bars.] (else-if: $numberofbars < 20)[fewer than twenty bars.] (else-if: $numberofbars is 20)[EXACTLY twenty bars!] (else-if: $numberofbars > 20)[more than twenty bars.] } In fact, you scored $numberofbars!{ }(if: $numberofbars is 0)[ In the stillness of deep night you ask yourself – what was the point of breaking into the chocolate bar factory if you weren't going to steal any chocolate bars?] <span style="background-color:#4c2e1b;padding-right:10px;padding-left:10px;">[[back to reference->reference]]</span>From around a corner down a dark hallway, the demon lurches!! (link-reveal:"Time to act!")[ (if: $thermometer is true)[You whip out your thermometer and check the temperature. It's cold! But that information doesn't help you! You've wasted valuable time! (link-reveal:"Press on!")[ Unfortunately, those few seconds spent fiddling with the thermometer spelled out your doom. The demon opens a hell portal and you fall into it. According to your thermometer it is very hot]]{ }(else:)[(if: $flashlight is true)[You shine your flashlight at the demon, momentarily blinding it. Your target is dead ahead! (link-reveal:"Let's go!")[(if: $holywater is true)[ Now's your chance! You uncork the holy water and fling it directly at the demon, turning it into easily vacuumed miasma. Good job! Have a bonus!]{ }(else:)[ But you have nothing else to offer in this situation. You take advantage of the demon's momentary overwhelm to flee. Your coworkers scoff at you.]]]{ }(else:)[(if: $holywater is true)[You uncork your holy water and fling it in the direction of the demon, but lacking sufficient light, you miss! (link-reveal:"Oh no!")[ The demon glides right for you and bites your face off.]]{ }(else:)[You rummage around in your pockets, turning up only lint and a nickel. (link-reveal:"Oops!")[ Feebly you invoke some saints. You manage to name a couple before your intestines are on the ceiling.]]]]] (display:"backtoreference")(if: (random: 0, 100) <= $probability)[Your roommate ate the cake. πŸ˜­πŸ’”](else:)[You ate it and it was delicious and your roommate said it was totally fine.] (display:"backtoreference"){(set:$phrases to (a:"Suddenly,"," a lime green frog jumps out,"," startling you so much you fall backwards."," As fast as a bouncing tennis ball,"," it hops over to the open window,"," leaps onto the sill,"," and vanishes into the outdoors.")) }You're in a room with a wooden box the size of a loaf of bread. (link:"Open it?")[{ (set:$timing to time) }(for: each _i, ...(range:1,$phrases's length))[(after:$timing + (_i * 500))[(print:$phrases's _i)]] ] (display:"backtoreference")[Hello. I see you've found this computer console. Well, please listen carefully, as time is running out. This facilty is at risk for containment breach unless you initiate the lockdown procedure. You need to go to the main security office and flip [1234 5678 9]<glitch1| yellow while [consectetur adipiscing elit]<glitch1| or else [In nec tellus suscipit, sagittis diam sed Nulla in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA]<glitch1| (display:"backtoreference")](text| (after:1s)[ (enchant: ?passage's chars, via (t8n-delay:pos * 30) + (t8n:'instant')) (show:?text) ]{(set:$dialogue to (a: "I saw you take that key from the minister's desk drawer.", "You're planning something, aren't you?", "I'm gonna tell on you! Unless...", "Unless you think you can make it worth my while to keep quiet...!", "What about it, huh?", )) (set:$step to 1) }Hold it right there, mister![]<next| ====><= (text-style:"buoy")[β–Ό]<continue|{ }(click-rerun:?continue)[(append:?next)[ (print:$dialogue's $step)(set: $step to it + 1)(if:$step > $dialogue's length)[(replace:?continue)[]]]] <== (display:"backtoreference")